﻿using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.AvalonEdit.Rendering;
using MahApps.Metro.Controls;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Xml;

namespace LunarSF.SHomeWorkshop.LunarMarkdownEditor
{
    /// <summary>
    /// PlainTextEditor.xaml 的交互逻辑
    /// </summary>
    public partial class PlainTextEditor : MetroWindow
    {
        /// <summary>
        /// 自定义高亮定义，完整定义。
        /// 但一千多行的帮助文档就明显延迟。
        /// </summary>
        private static IHighlightingDefinition markdownHighlighting;

        private static Converter.ModifiedToText modifiedToTextConverter = new LunarMarkdownEditor.Converter.ModifiedToText();
        /// <summary>
        /// [只读]bool to "已修改 未修改" 的字符串的转换器。
        /// </summary>
        public static Converter.ModifiedToText ModifiedToTextConverter { get { return modifiedToTextConverter; } }

        /// <summary>
        /// [静态构造方法]
        /// </summary>
        static PlainTextEditor()
        {
            Stream s = typeof(MainWindow).Assembly.GetManifestResourceStream("LunarSF.SHomeWorkshop.LunarMarkdownEditor.MarkdownSyntaxHightlightRulesets.xshd");
            if (s != null)
            {
                using (XmlReader reader = new XmlTextReader(s))
                {
                    markdownHighlighting = ICSharpCode.AvalonEdit.Highlighting.Xshd.
                        HighlightingLoader.Load(reader, HighlightingManager.Instance);
                }
            }
        }

        /// <summary>
        /// [构造方法]创建一个纯文本编辑器。没有什么语法高亮之类的特殊功能。
        /// </summary>
        /// <param name="filePath">要编辑的文件的完整路径。</param>
        public PlainTextEditor(string filePath)
        {
            InitializeComponent();

            this.Title = Globals.AppName;
            this.filePath = filePath;


            editorBase.Options.ShowSpaces = false;
            editorBase.Options.ShowTabs = true;
            editorBase.Options.ConvertTabsToSpaces = false;
            editorBase.Options.AutoAlignTabs = false;
            editorBase.Options.HighlightCurrentLine = true;
            editorBase.Options.ShowEndOfLine = false;
            editorBase.ShowLineNumbers = true;
            editorBase.WordWrap = false;

            // HighlightingManager.Instance.RegisterHighlighting("Markdown Highlighting", new string[] { ".md" }, markdownHighlighting);
            // 不能重复注册同一后缀名的高亮显示方案！

            editorBase.SyntaxHighlighting = HighlightingManager.Instance.GetDefinitionByExtension(".md");

            // 其实，只需要添加对双斜框注释行的支持即可。
            editorBase.SyntaxHighlighting.MainRuleSet.Rules.Add(
                new HighlightingRule()
                {
                    Color = new HighlightingColor()
                    {
                        Foreground = new CustomizedBrush(Colors.DarkGreen),
                    },
                    Regex = new System.Text.RegularExpressions.Regex(@"^//.*$"),
                }
                );
        }

        /// <summary>
        /// Copied from:
        /// https://stackoverflow.com/questions/11806764/adding-syntax-highlighting-rules-to-avalonedit-programmatically
        /// </summary>
        internal sealed class CustomizedBrush : HighlightingBrush
        {
            private readonly SolidColorBrush brush;
            public CustomizedBrush(Color color)
            {
                brush = CreateFrozenBrush(color);
            }

            public CustomizedBrush(System.Drawing.Color c)
            {
                var c2 = System.Windows.Media.Color.FromArgb(c.A, c.R, c.G, c.B);
                brush = CreateFrozenBrush(c2);
            }

            public override Brush GetBrush(ITextRunConstructionContext context)
            {
                return brush;
            }

            public override string ToString()
            {
                return brush.ToString();
            }

            private static SolidColorBrush CreateFrozenBrush(Color color)
            {
                SolidColorBrush brush = new SolidColorBrush(color);
                brush.Freeze();
                return brush;
            }
        }

        private string filePath;
        /// <summary>
        /// 要编辑的文件的完整路径。
        /// </summary>
        public string FilePath
        {
            get { return filePath; }
        }

        /// <summary>
        /// 放弃编辑，关闭窗口。
        /// </summary>
        private void btnClose_Click(object sender, RoutedEventArgs e)
        {
            this.DialogResult = false;
            this.Close();
            return;
        }

        /// <summary>
        /// 保存文件，关闭窗口。
        /// </summary>
        private void btnSave_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                File.WriteAllText(this.filePath, editorBase.Text, Encoding.UTF8);
            }
            catch (Exception ex)
            {
                LMessageBox.Show(ex.Message, Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
            }

            this.DialogResult = true;
            this.Close();
            return;
        }
    }
}
